/**
 * Utility functions for Iroh integration
 */

interface ShareTicketInfo {
  sourceNode: string;
  documentId: string;
  timestamp: number;
}

export class IrohUtils {
  /**
   * Generate a unique node ID
   */
  static generateNodeId(): string {
    return `node_${Date.now()}_${Math.random().toString(36).substring(2)}`;
  }

  /**
   * Generate a unique document ID
   */
  static generateDocumentId(): string {
    return `doc_${Date.now()}_${Math.random().toString(36).substring(2)}`;
  }

  /**
   * Calculate hash for data (simplified implementation)
   * In a real implementation, you would use a proper hash function like blake3
   */
  static async calculateHash(data: Uint8Array): Promise<string> {
    // Simple hash function for demo purposes
    let hash = 0;
    for (let i = 0; i < data.length; i++) {
      const char = data[i];
      hash = (hash << 5) - hash + char;
      hash = hash & hash; // Convert to 32-bit integer
    }
    return `hash_${Math.abs(hash).toString(16)}_${data.length}`;
  }

  /**
   * Generate a share ticket for a document
   */
  static generateShareTicket(nodeId: string, documentId: string): string {
    const ticket = {
      sourceNode: nodeId,
      documentId,
      timestamp: Date.now(),
    };

    // In a real implementation, this would be a proper iroh ticket format
    return btoa(JSON.stringify(ticket));
  }

  /**
   * Parse a share ticket
   */
  static parseShareTicket(ticket: string): ShareTicketInfo {
    try {
      const decoded = atob(ticket);
      return JSON.parse(decoded);
    } catch (error) {
      throw new Error("Invalid share ticket format");
    }
  }

  /**
   * Format file size in human readable format
   */
  static formatFileSize(bytes: number): string {
    if (bytes === 0) return "0 Bytes";

    const k = 1024;
    const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
    const i = Math.floor(Math.log(bytes) / Math.log(k));

    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
  }

  /**
   * Validate node ID format
   */
  static isValidNodeId(nodeId: string): boolean {
    return /^node_\d+_[a-z0-9]+$/.test(nodeId);
  }

  /**
   * Validate document ID format
   */
  static isValidDocumentId(documentId: string): boolean {
    return /^doc_\d+_[a-z0-9]+$/.test(documentId);
  }

  /**
   * Generate a QR code data for sharing
   */
  static generateQRData(ticket: string): string {
    return `iroh://share/${ticket}`;
  }

  /**
   * Parse QR code data
   */
  static parseQRData(qrData: string): string {
    const match = qrData.match(/^iroh:\/\/share\/(.+)$/);
    if (!match) {
      throw new Error("Invalid QR code format");
    }
    return match[1];
  }

  /**
   * Get connection status description
   */
  static getConnectionStatus(
    isConnected: boolean,
    connectionCount: number,
  ): string {
    if (!isConnected) {
      return "Disconnected";
    }

    if (connectionCount === 0) {
      return "Online (No peers)";
    }

    return `Online (${connectionCount} peer${connectionCount === 1 ? "" : "s"})`;
  }

  /**
   * Estimate transfer time based on file size and connection speed
   */
  static estimateTransferTime(
    bytes: number,
    speedBytesPerSecond: number = 1024 * 100,
  ): string {
    if (speedBytesPerSecond <= 0) {
      return "Unknown";
    }

    const seconds = bytes / speedBytesPerSecond;

    if (seconds < 60) {
      return `${Math.ceil(seconds)}s`;
    } else if (seconds < 3600) {
      return `${Math.ceil(seconds / 60)}m`;
    } else {
      return `${Math.ceil(seconds / 3600)}h`;
    }
  }
}
